package com.demo.compass.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.SelectItem;

import log4j.controller.Utilitarios;

import org.apache.log4j.Logger;
import org.compass.gps.impl.SingleCompassGps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;

import test.ObtenerLog4jTest;


import com.demo.persistencia.generica.dao.GenericDao;
import com.demo.persistencia.generica.dao.impl.CompassDaoImpl;
import com.demo.persistencia.generica.modelo.Employee;
import com.demo.persistencia.generica.modelo.Log4jdata;
import com.demo.persistencia.generica.modelo.ResultadoSearch;
import com.demo.persistencia.generica.util.HibernateUtil;

@ManagedBean(name = "motorBusquedaCompass")
@SessionScoped
public class MotorBusquedaCompass extends HibernateUtil  implements Serializable {

	private static final long serialVersionUID = 1L;

	private static Logger log = Logger.getLogger(MotorBusquedaCompass.class);
	private List<SelectItem> lstLevel;
	private List<ResultadoSearch> lstResultado;
	private String sInput;
	private SelectItem[] lstClasesSearchables;
	private SelectItem[] lstPaquetes;
	private String sClassSeleccionada;
	private List<ResultadoSearch> lstNivelLogger;
    private String sPaquete;
    private String sValuePaquete;
    
	//@Autowired
	private SingleCompassGps compassGps;
	//@Autowired
	private CompassDaoImpl compass;
	@Autowired(required=false)
	@Qualifier(value="initLogging")
	MethodInvokingFactoryBean logInitDao;
	HashMap<String, String> mapconfig=  new HashMap<String, String>();
	public void setLogInitDao(MethodInvokingFactoryBean logInitDao) {
		this.logInitDao = logInitDao;
	}
	public MotorBusquedaCompass() {
		
		IniciarContextoSpring();
		lstResultado = new ArrayList<ResultadoSearch>();
		lstNivelLogger=new ArrayList<ResultadoSearch>();
		lstLevel=new ArrayList<SelectItem>();
		
		//indexar();
		listarClasesSearchables();
		listarPaquetesCombo();
		listacomboboxLevel();
		
		//metodoLoggerCambiable();
		
		//crearTest();
		//modificarTest();
	}
	public void metodoLoggerCambiable(){
		log.info("En el metodoLogger");
		logInitDao = (MethodInvokingFactoryBean) getContextoSpring().getBean(MethodInvokingFactoryBean.class);
		
		log.info("logInitDao : " +logInitDao);
		try {
			if(logInitDao!=null){
				grabarNivelPaquete();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}
	
	public void addNivelLogPaquete(){
		log.info("addNivelLogPaquete : sPaquete " + sPaquete + " sValuePaquete " +sValuePaquete);
		if(sPaquete!="" && sValuePaquete!=""){
			mapconfig.put(sPaquete, sValuePaquete);
			lstNivelLogger.add(new ResultadoSearch(sPaquete.toString(), sValuePaquete.toString()));
		}
	}
	
	public void grabarNivelPaquete(){
		try {
			if(logInitDao!=null){
				Object[] arrayArgumentos=logInitDao.getArguments();
				String srutaProperties = arrayArgumentos[0].toString().substring(arrayArgumentos[0].toString().lastIndexOf(':')+1, arrayArgumentos[0].toString().length());
				setearProperties(srutaProperties);
				setLstNivelLogger(new ArrayList<ResultadoSearch>());
				setMapconfig(new HashMap<String, String>());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void eliminar(){
		String sIdParam=Utilitarios.capturarParametro("idParam");
		log.info("sIdParam : " +sIdParam);
		ResultadoSearch bean= new ResultadoSearch();	
		bean.setsKeyString(sIdParam);
		lstNivelLogger.remove(bean );
	}
	
	public void setearProperties(String sProperties){
		log.info("En el setearValores");
		  Properties dbProps;
		  InputStream inputStream=null;
		
		  try {
		   System.out.println(" ObtenerLog4jTest.class.getClassLoader()." +ObtenerLog4jTest.class.getClassLoader().getResource("log4j/log4j.properties") );
		   inputStream= MotorBusquedaCompass.class.getClassLoader().getResourceAsStream(sProperties);
		  
		  dbProps = new Properties();
		  dbProps.load(inputStream);
		  inputStream.close();

		  Iterator<Entry<String, String>> iter = mapconfig.entrySet().iterator();
		  Map.Entry  e;

		  while (iter.hasNext()) {
		  e = (Map.Entry)iter.next();
		  //System.out.println("Clave: " + e.getKey() + " | Valor: " + e.getValue());
		  dbProps.setProperty(e.getKey().toString(),e.getValue().toString());
		                         }
		  dbProps.store(new FileOutputStream("C:/BUCKUPSAMIRA/Archivos/Workspaces/Log4jTestFinal/CompassDemo02/resources/log4j/log4j.properties"), null);
			
		  } catch (Exception e) {
		 
		  log.error("El archivo "+sProperties+" NO ha sido cargado exitosamente"); 
		           e.printStackTrace();
		  }
	}
	public void busqueda(){
		lstResultado = new ArrayList<ResultadoSearch>();
		System.out.println("Contiene o no el : "+sInput.lastIndexOf(':'));
		if(sInput.lastIndexOf(':')!=0){
			busquedaEntidad();
		}else{
			buscarXAtributo();
		}
	}
	public void busquedaEntidad() {
	    log.info("En la busqueda: " + sInput);
		
		if(sClassSeleccionada.equals("Todos")){
			sClassSeleccionada="TbEspejo";
		}
		if (sInput != "" && sClassSeleccionada != "") {
			try {
				System.out.println(" sClassSeleccionada: " + sClassSeleccionada);
                
				String clsName = sClassSeleccionada; 
				Class cls = Class.forName("com.demo.persistencia.generica.modelo."+ clsName);
				Object clsInstance = (Object) cls.newInstance();

				Buscador searchDAO = (Buscador) HibernateUtil.getContextoSpring().getBean("searchDao");
				String searchText = sInput;
				Map<String, List<Object>> retorno = searchDAO.search(searchText);
				Integer iItem=0;
				System.out.println(retorno.size() + "  " + retorno.isEmpty() +" : " + retorno.toString());
				if (retorno.size()!= 0 && retorno.toString()!="" &&!retorno.isEmpty()) {
					String objectName = clsInstance.getClass().getName();
					List<Object> lst = retorno.get(objectName);
					if(lst!=null){
						ResultadoSearch rs=null;
						for (Object objeto : lst) {
							iItem++;
						rs = new ResultadoSearch();
						rs.setiId(iItem);
						rs.setValor(objeto.toString());
						lstResultado.add(rs);
						}
					}
					
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (Exception e) {
				System.out.println(e.getMessage());
				e.printStackTrace();
			}
		}
	}

	
	public void buscarXAtributo(){
		System.out.println("Here buscarXAtributo" );
		Class cls;
		try {
		cls = Class.forName("com.demo.persistencia.generica.modelo."+sClassSeleccionada);
		
		Object clsInstance = (Object) cls.newInstance();
        List lstAtributo = new ArrayList<Object>();
      //"clase:*"  
        lstAtributo =compass.buscarPaginado(sInput,10);
    	Integer iItem=0;
		ResultadoSearch rs=null;
		for (Object objeto : lstAtributo) {
			iItem++;
			rs = new ResultadoSearch();
			rs.setiId(iItem);
			rs.setValor(objeto.toString());
			lstResultado.add(rs);
		}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	public void listarClasesSearchables() {
		log.info("En el listarClasesSearchables ");
		lstClasesSearchables = Utilitarios.getSelectItems(Utilitarios.listarCLasesSearchables(), false);
		for (SelectItem svalor : lstClasesSearchables) {
			if(svalor.getLabel().equals("TbEspejo")){
				svalor.setLabel("Todos");
			}
		}
	}
	
	public void listarPaquetesCombo(){
		lstPaquetes=Utilitarios.getSelectItems(this.listarPaquetes(), false);
		
	}
	public void listacomboboxLevel() {

		lstLevel = new ArrayList<SelectItem>();
		lstLevel.add(new SelectItem(Utilitarios.TRACE, "TRACE"));
		lstLevel.add(new SelectItem(Utilitarios.DEBUG, "DEBUG"));
		lstLevel.add(new SelectItem(Utilitarios.INFO, "INFO"));
		lstLevel.add(new SelectItem(Utilitarios.WARN, "WARN"));
		lstLevel.add(new SelectItem(Utilitarios.ERROR, "ERROR"));
		lstLevel.add(new SelectItem(Utilitarios.FATAL, "FATAL"));

	}
	public  List<String> listarPaquetes(){
		
		HashMap<Integer,String>  mapconfig=  new HashMap();
		
		mapconfig.put(1,"log4j.logger.org.hibernate");
		mapconfig.put(2,"log4j.logger.org.springframework");
		mapconfig.put(3,"log4j.logger.org.compass.core");
		List<String> lstPaquetes = new ArrayList<String>();
		
		Iterator<Entry<Integer, String>> iter = mapconfig.entrySet().iterator();
		Map.Entry  e;
		ResultadoSearch bean ;
		while (iter.hasNext()) {
		e = (Map.Entry)iter.next();
		//bean=new ResultadoSearch(Integer.parseInt(e.getKey().toString()),e.getValue().toString());
		System.out.println("Clave: " + e.getKey() + " | Valor: " + e.getValue());
		lstPaquetes.add(e.getValue().toString());
		}
		
		return  lstPaquetes;
	}

	@SuppressWarnings({ "unchecked" })
	public void indexar() {
		System.out.println("En el indexar");
		compass = (CompassDaoImpl<Log4jdata>) getContextoSpring().getBean("compassDao");
	}

	
	  public void crearTest() {
			GenericDao<Employee, Integer> entidadDAO = (GenericDao<Employee, Integer>) HibernateUtil.getContextoSpring().getBean("genericoDao");
			Employee  entidad = new Employee();
		    entidad.setEmployeeID("algo01");
			entidad.setFirstName("Samira");
			Employee entidadRetorno = entidadDAO.insertar(entidad);
			
		     System.out.println("> Resultado de crearTest Prueba: "+entidadRetorno.getFirstName());
		 }
	  public void modificarTest() {
			GenericDao<Log4jdata, Integer> entidadDAO = (GenericDao<Log4jdata, Integer>) HibernateUtil.getContextoSpring().getBean("genericoDao");
			Log4jdata  entidad = new Log4jdata();
		    entidad.setId(new BigDecimal(9999));
			entidad.setMensaje("SAMIRA LISBOA");
			entidad.setInflocalizacion("caramba");
			Log4jdata entidadRetorno = entidadDAO.modificar(entidad);
		     System.out.println("> Resultado de crearTest MOdificiar del COntrolleer: "+entidadRetorno.getMensaje());
		 }
	public List<ResultadoSearch> getLstResultado() {
		return lstResultado;
	}

	public void setLstResultado(List<ResultadoSearch> lstResultado) {
		this.lstResultado = lstResultado;
	}

	public String getsInput() {
		return sInput;
	}

	public void setsInput(String sInput) {
		this.sInput = sInput;
	}

	public SelectItem[] getLstClasesSearchables() {
		return lstClasesSearchables;
	}

	public void setLstClasesSearchables(SelectItem[] lstClasesSearchables) {
		this.lstClasesSearchables = lstClasesSearchables;
	}

	public String getsClassSeleccionada() {
		return sClassSeleccionada;
	}

	public void setsClassSeleccionada(String sClassSeleccionada) {
		this.sClassSeleccionada = sClassSeleccionada;
	}
	public List<ResultadoSearch> getLstNivelLogger() {
		return lstNivelLogger;
	}
	public void setLstNivelLogger(List<ResultadoSearch> lstNivelLogger) {
		this.lstNivelLogger = lstNivelLogger;
	}
	public String getsPaquete() {
		return sPaquete;
	}
	public void setsPaquete(String sPaquete) {
		this.sPaquete = sPaquete;
	}
	public String getsValuePaquete() {
		return sValuePaquete;
	}
	public void setsValuePaquete(String sValuePaquete) {
		this.sValuePaquete = sValuePaquete;
	}
	public SelectItem[] getLstPaquetes() {
		return lstPaquetes;
	}
	public void setLstPaquetes(SelectItem[] lstPaquetes) {
		this.lstPaquetes = lstPaquetes;
	}
	public HashMap<String, String> getMapconfig() {
		return mapconfig;
	}
	public void setMapconfig(HashMap<String, String> mapconfig) {
		this.mapconfig = mapconfig;
	}
	public List<SelectItem> getLstLevel() {
		return lstLevel;
	}
	public void setLstLevel(List<SelectItem> lstLevel) {
		this.lstLevel = lstLevel;
	}

}
